package com.yami.shop.api.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.enums.InteractPowerEnum;
import com.yami.shop.bean.enums.SendType;
import com.yami.shop.bean.event.SendPersonMessageEvent;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.param.NotifyTemplateParam;
import com.yami.shop.bean.vo.CommentVO;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.enums.ECommentSource;
import com.yami.shop.common.enums.ECommentType;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.IPHelper;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.common.util.StringUtils;
import com.yami.shop.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * 功能描述: 评论点赞
 * @Author: LSR
 * @Date: 2022/12/28 10:00
 */

@RestController
@RequestMapping("/api/blogComment")
@Tag(name="评论点赞接口")
@Slf4j
public class BlogCommentController {

    @Autowired
    private BlogService blogService;
    @Autowired
    private FriendService friendService;
    @Autowired
    private CommentService commentService;
    @Autowired
    private UserService userService;
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private NotifyLogService notifyLogService;
    @Autowired
    private UserBlockService userBlockService;
    @Autowired
    private ReportService reportService;
    @Autowired
    private MeltCloudUserRemarkService userRemarkService;
    /**
     * 获取评论列表
     * 盖楼接口
     * @param commentVO
     * @param
     * @return
     */
    @Operation(summary =  "获取评论列表", description = "获取评论列表")
    @GetMapping("/getList")
    public ServerResponseEntity<IPage<Comment>> getList(PageParam page ,  CommentVO commentVO) {
        QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNull(commentVO.getBlogUid())) {
            queryWrapper.eq("blog_uid", commentVO.getBlogUid());
        }
        queryWrapper.eq("source", commentVO.getSource());
        //分页
        queryWrapper.eq("status", 1);
        queryWrapper.isNull("to_uid");
        queryWrapper.orderByDesc("create_time");
        queryWrapper.eq("type", ECommentType.COMMENT);
        // 查询出所有的一级评论，进行分页显示 即回复id为null
        IPage<Comment> pageList = commentService.page(page, queryWrapper);
        List<Comment> list = pageList.getRecords();
        List<Long> firstUidList = new ArrayList<>();
        //获取所有富一代 评论id
        list.forEach(item -> {
            firstUidList.add(item.getUid());
        });

        if (firstUidList.size() > 0) {
            // 查询一级评论下的子评论
            QueryWrapper<Comment> notFirstQueryWrapper = new QueryWrapper<>();
            notFirstQueryWrapper.in("first_comment_uid", firstUidList);
            notFirstQueryWrapper.eq("status", 1);
            List<Comment> notFirstList = commentService.list(notFirstQueryWrapper);
            // 将子评论加入总的评论中
            if (notFirstList.size() > 0) {
                list.addAll(notFirstList);
            }
        }

        List<String> userUidList = new ArrayList<>();
        list.forEach(item -> {
            String userUid = item.getUserUid();
            String toUserUid = item.getToUserUid();
            if (StringUtils.isNotEmpty(userUid)) {
                userUidList.add(item.getUserUid());
            }
            if (StringUtils.isNotEmpty(toUserUid)) {
                userUidList.add(item.getToUserUid());
            }
        });
        Collection<User> userList = new ArrayList<>();
        if (userUidList.size() > 0) {
            userList = userService.listByIds(userUidList.stream().distinct().collect(Collectors.toList()));
        }

        // 过滤掉用户的敏感信息
        List<User> filterUserList = new ArrayList<>();
        userList.forEach(item -> {
            User user = new User();
            user.setPic(item.getPic());
            user.setUserId(item.getUserId());
            user.setNickName(item.getNickName());
            user.setIsHasRealName(StrUtil.isNotEmpty(item.getRealName()));
            filterUserList.add(user);
        });
        if(userUidList.contains("admin")){
            User user = new User();
//            user.setPic(item.getPic());
            user.setUserId("admin");
            user.setNickName("平台");
            filterUserList.add(user);
        }
        List<User> filterUserListTo = filterUserList.stream().distinct().collect(Collectors.toList());
        Map<String, User> userMap = filterUserListTo.stream().collect(Collectors.toMap(User::getUserId, Function.identity()));
        Map<Long, Comment> commentMap = new HashMap<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getUserUid())) {
                item.setUser(userMap.get(item.getUserUid()));
            }
            if (StringUtils.isNotEmpty(item.getToUserUid())) {
                item.setToUser(userMap.get(item.getToUserUid()));
            }
            commentMap.put(item.getUid(), item);
        });

        // 设置一级评论下的子评论
        Map<Long, List<Comment>> toCommentListMap = new HashMap<>();
        for (int a = 0; a < list.size(); a++) {
            List<Comment> tempList = new ArrayList<>();
            for (int b = 0; b < list.size(); b++) {
                if (list.get(a).getUid().equals(list.get(b).getToUid())) {
                    tempList.add(list.get(b));
                }
            }
            toCommentListMap.put(list.get(a).getUid(), tempList);
        }
        List<Comment> firstComment = new ArrayList<>();
        list.forEach(item -> {
            if (ObjectUtil.isNull(item.getToUid())) {
                firstComment.add(item);
            }
        });
        pageList.setRecords(commentService.getCommentReplys(firstComment, toCommentListMap));
        return ServerResponseEntity.success(pageList);
    }

    /** 一级品类或者二级评论单独接口
     * blogUid 博客id  toUid 为空 代表博客的首评列表 不为空 代表子品论列表  userUid 传参代表用户登录 praiseIsMe 如果点赞会返回true 未登录或者登录点赞都返回false
     * @param page
     * @param commentVO
     * @return
     */
    @Operation(summary =  "获取博客评论列表", description = "获取评论列表")
    @GetMapping("/getListByBlogUid")
    public ServerResponseEntity<IPage<Comment>> getListByBlogUid(PageParam page,CommentVO commentVO) {
        if(ObjectUtil.isNull(commentVO.getBlogUid())){
            return ServerResponseEntity.showFailMsg("参数不全");
        }
        Blog blog = blogService.getById(commentVO.getBlogUid());
        QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("blog_uid", commentVO.getBlogUid());
        queryWrapper.eq("source", "1");
        if(ObjectUtil.isNull(commentVO.getToUid())){
            queryWrapper.isNull("to_uid");
        }else{
            queryWrapper.eq("to_uid",commentVO.getToUid());
        }
        //分页
        queryWrapper.eq("status", 1);
        queryWrapper.eq("type", ECommentType.COMMENT);
        if (StringUtils.isNotEmpty(commentVO.getUserUid())) {
            int sou = blog.getType().equals(0) ? 0 : 1;
            List<Long> objIds = reportService.listObjs(new LambdaQueryWrapper<Report>().select(Report::getReportObjId).eq(Report::getReportSou, sou).eq(Report::getReportType, 1).eq(Report::getUserId, commentVO.getUserUid()), o -> Long.valueOf(o.toString()));
            if (objIds.size() > 0) {
                queryWrapper.notIn("uid", objIds);
            }
            LambdaQueryWrapper<UserBlock> eq = Wrappers.lambdaQuery(UserBlock.class).select(UserBlock::getBlockUserId).eq(UserBlock::getUserId, commentVO.getUserUid());
            List<String> blockUserIds = userBlockService.listObjs(eq, ub -> ub.toString());
            if (CollUtil.isNotEmpty(blockUserIds)) {
                queryWrapper.notIn("user_uid", blockUserIds);
            }
        }
        queryWrapper.orderByDesc("create_time");
        // 查询出该文章下所有的评论
        IPage<Comment> pageList = commentService.page(page, queryWrapper);
        List<Comment> list = pageList.getRecords();

        // 所有用户
        Set<String> userUidList = new HashSet<>();
        // 查询所有品论id
        List<Long> toCommentUidList = new ArrayList<>();
        list.forEach(item -> {
            String userUid = item.getUserUid();
            if (StringUtils.isNotEmpty(userUid)) {
                userUidList.add(item.getUserUid());
            }
            toCommentUidList.add(item.getUid());
        });
        //获取用户分组对象
        Collection<User> userList = new ArrayList<>();
        Map<String, String> remarkMap = new HashMap<>();
        if (userUidList.size() > 0) {
            userList = userService.listByIds(userUidList);
            if (StringUtils.isNotEmpty(commentVO.getUserUid())) {
                List<MeltCloudUserRemark> remarkList = userRemarkService.list(Wrappers.lambdaQuery(MeltCloudUserRemark.class).eq(MeltCloudUserRemark::getUserId, commentVO.getUserUid()).eq(MeltCloudUserRemark::getType, 1).in(MeltCloudUserRemark::getObjId, userUidList));
                remarkMap = remarkList.stream().collect(Collectors.toMap(MeltCloudUserRemark::getObjId, MeltCloudUserRemark::getRemark));
            }
        }
        // 过滤掉用户的敏感信息
        List<User> filterUserList = new ArrayList<>();
        Map<String, String> finalRemarkMap = remarkMap;
        userList.forEach(item -> {
            User user = new User();
            user.setPic(item.getPic());
            user.setUserId(item.getUserId());
            user.setStatus(item.getStatus());
            String name = item.getNickName();
            if (StringUtils.isNotEmpty(commentVO.getUserUid()) && StringUtils.isNotEmpty(finalRemarkMap.get(item.getUserId()))) {
                name = finalRemarkMap.get(item.getUserId());
            }
            user.setNickName(name);
            user.setIsHasRealName(StrUtil.isNotEmpty(item.getRealName()));
            user.setBlogType(getUserBlogType(blog.getUserUid(),commentVO.getUserUid(),item.getUserId()));
            user.setProvince(IPHelper.getIpProvinceAddr(item.getUserRegip()));
            filterUserList.add(user);
        });

        if(userUidList.contains("admin")){
            User user = new User();
//            user.setPic(item.getPic());
            user.setUserId("admin");
            user.setNickName("平台");
            user.setStatus(1);
            filterUserList.add(user);
        }
        List<User> filterUserListTo = filterUserList.stream().distinct().collect(Collectors.toList());
        Map<String, User> userMap = filterUserListTo.stream().collect(Collectors.toMap(User::getUserId, Function.identity()));
        // 根据一级id，用来存放全部回复二级的评论
        List<Comment> allCommentList = new ArrayList<>();
        if (toCommentUidList.size() > 0) {
            QueryWrapper<Comment> wrapper = new QueryWrapper<>();
            wrapper.eq("blog_uid", commentVO.getBlogUid());
            wrapper.eq("source", "1");
            wrapper.in("first_comment_uid",toCommentUidList);
            //分页
            wrapper.eq("status", 1);
            wrapper.eq("type", ECommentType.COMMENT);
            int sou = blog.getType().equals(0) ? 0 : 1;
            List<Long> objIds = reportService.listObjs(new LambdaQueryWrapper<Report>().select(Report::getReportObjId).eq(Report::getReportSou, sou).eq(Report::getReportType, 1).eq(Report::getUserId, commentVO.getUserUid()), o -> Long.valueOf(o.toString()));
            if (objIds.size() > 0) {
                wrapper.notIn("uid", objIds);
            }
            // 查询出该文章下所有的子评论
            allCommentList = commentService.list(wrapper);
        }
        //分组 看每个富一代 下回复的数量
        Map<Long, Long> collect = allCommentList.stream().collect(Collectors.groupingBy(t -> t.getFirstCommentUid(), Collectors.counting()));

        // 根据一级id，获取点赞数
        List<Comment> allPraiseList = new ArrayList<>();
        if (toCommentUidList.size() > 0) {
            QueryWrapper<Comment> wrapper = new QueryWrapper<>();
            wrapper.eq("blog_uid", commentVO.getBlogUid());
            wrapper.eq("source", "1");
            wrapper.in("to_uid",toCommentUidList);
            //分页
            wrapper.eq("status", 1);
            wrapper.eq("type", ECommentType.PRAISE);
            // 查询出该文章下所有的子评论
            allPraiseList = commentService.list(wrapper);
        }
        //分组 看每个富一代 下回复的数量
        Map<Long, Long> collect1 = allPraiseList.stream().collect(Collectors.groupingBy(t -> t.getToUid(), Collectors.counting()));
        Map<Long, List<Comment>> collect2 = allPraiseList.stream().collect(Collectors.groupingBy(Comment::getToUid));
        // 定义一个评论Map键值对
        list.forEach(item -> {
            if(!ObjectUtil.isNull(item.getIp())){
                item.setIp(IPHelper.getIpProvinceAddr(item.getIp()));
            }
            //设置用户信息
            if (StringUtils.isNotEmpty(item.getUserUid())&& userMap.get(item.getUserUid())!=null) {
                item.setUser(userMap.get(item.getUserUid()));
            }
            long l1 = ObjectUtil.isNull(collect.get(item.getUid())) ? 0 : collect.get(item.getUid());
            //设置回复数
            item.setReplyListCount(l1);
            //点赞数
            long l2 = ObjectUtil.isNull(collect1.get(item.getUid())) ? 0 : collect1.get(item.getUid());
            item.setPraiseCount(l2);
            List<Comment> comments = collect2.get(item.getUid());
            if(StrUtil.isNotEmpty(commentVO.getUserUid()) && !ObjectUtil.isNull(comments)){
                List<Comment> collect3 = comments.stream().filter(s -> s.getUserUid().equals(commentVO.getUserUid())).collect(Collectors.toList());
                item.setPraiseIsMe(collect3.size()>0? true:false);
            }else item.setPraiseIsMe(false);
        });
        pageList.setRecords(list);
        return ServerResponseEntity.success(pageList);
    }
    // blogUserId 文章作者id currUserId 登录用户id paramUserId当前id
    private String getUserBlogType(String blogUserId,String currUserId,String paramUserId){
        String type = null;
        if(StrUtil.isNotEmpty(currUserId) && paramUserId.equals(currUserId)){
            type = "3";
        }else if(paramUserId.equals(blogUserId)){
            type = "2";
        }else{
            type = "1";
        }
        return type;
    }

    /**
     * 二级接口 三级和子集和二级同列显示
     * @param page
     * @param commentVO
     * @return
     */
    @Operation(summary =  "获取二级博客评论列表", description = "获取评论列表")
    @GetMapping("/getListByBlogUidAndToUid")
    public ServerResponseEntity<IPage<Comment>> getListByBlogUidAndToUid(PageParam page,CommentVO commentVO) {
        if(ObjectUtil.isNull(commentVO.getBlogUid()) || ObjectUtil.isNull(commentVO.getToUid())){
            throw new YamiShopBindException("yami.sys.illegalArgument");
        }
        Blog blog = blogService.getById(commentVO.getBlogUid());
        //获取二级集合
        QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("blog_uid", commentVO.getBlogUid());
        queryWrapper.eq("source", "1");
        queryWrapper.eq("to_uid",commentVO.getToUid());
        //分页
        queryWrapper.eq("status", 1);
        queryWrapper.eq("type", ECommentType.COMMENT);
        // 举报的评论id集
        List<Long> objIds = new ArrayList<>();
        // 拉黑的用户id集
        List<String> blockUserIds = new ArrayList<>();
        if (StringUtils.isNotEmpty(commentVO.getUserUid())) {
            int sou = blog.getType().equals(0) ? 0 : 1;
            objIds = reportService.listObjs(new LambdaQueryWrapper<Report>().select(Report::getReportObjId).eq(Report::getReportSou, sou).eq(Report::getReportType, 1).eq(Report::getUserId, commentVO.getUserUid()), o -> Long.valueOf(o.toString()));
            if (objIds.size() > 0) {
                queryWrapper.notIn("uid", objIds);
            }
            LambdaQueryWrapper<UserBlock> eq = Wrappers.lambdaQuery(UserBlock.class).select(UserBlock::getBlockUserId).eq(UserBlock::getUserId, commentVO.getUserUid());
            blockUserIds = userBlockService.listObjs(eq, ub -> ub.toString());
            if (CollUtil.isNotEmpty(blockUserIds)) {
                queryWrapper.notIn("user_uid", blockUserIds);
            }
        }
        queryWrapper.orderByDesc("create_time");
        // 查询出该文章下所有的评论
        IPage<Comment> pageList = commentService.page(page, queryWrapper);
        List<Comment> list = pageList.getRecords();
        // 所有用户
        Set<String> userUidList = new HashSet<>();
        //根据二级id查询所有
        QueryWrapper<Comment> wrapper = new QueryWrapper<>();
        wrapper.eq("blog_uid", commentVO.getBlogUid());
        wrapper.eq("source", "1");
        wrapper.eq("first_comment_uid",commentVO.getToUid());
        wrapper.eq("status", 1);
        wrapper.eq("type", ECommentType.COMMENT);
        if (StringUtils.isNotEmpty(commentVO.getUserUid())) {
            if (CollUtil.isNotEmpty(objIds)) {
                wrapper.notIn("uid", objIds);
            }
           if (CollUtil.isNotEmpty(blockUserIds)) {
               wrapper.notIn("user_uid", blockUserIds);
            }
        }
        wrapper.orderByAsc("create_time");
        List<Comment> listAll = commentService.list(wrapper);
        List<Comment> finalResultList = new ArrayList<>();
        list.forEach(item -> {
            finalResultList.add(item);//存放二级
            List<Comment> parmaList = new ArrayList<>();
            commentService.getToCommentList(item, listAll, parmaList);
            finalResultList.addAll(parmaList);//存放自己
        });
        //最终结果
        List<Comment> resultList = new ArrayList<>();
        resultList.addAll(finalResultList);
        //获取回复数量
        Map<Long, Long> collectReplayCount = listAll.stream().collect(Collectors.groupingBy(t -> t.getToUid(), Collectors.counting()));
        Map<Long, Comment> commentMap = listAll.stream().collect(Collectors.toMap(Comment::getUid, Function.identity()));
        // 查询所有二级评论id
        List<Long> toCommentUidList = new ArrayList<>();
        resultList.forEach(item -> {
            String userUid = item.getUserUid();
            if (StringUtils.isNotEmpty(userUid)) {
                userUidList.add(userUid);
            }
            String userToUid = item.getToUserUid();
            if (StringUtils.isNotEmpty(userToUid)) {
                userUidList.add(userToUid);
            }
            toCommentUidList.add(item.getUid());
        });

        //获取用户分组对象
        Collection<User> userList = new ArrayList<>();
        Map<String, String> remarkMap = new HashMap<>();
        if (userUidList.size() > 0) {
            userList = userService.listByIds(userUidList);
            if (StringUtils.isNotEmpty(commentVO.getUserUid())) {
                List<MeltCloudUserRemark> remarkList = userRemarkService.list(Wrappers.lambdaQuery(MeltCloudUserRemark.class).eq(MeltCloudUserRemark::getUserId, commentVO.getUserUid()).eq(MeltCloudUserRemark::getType, 1).in(MeltCloudUserRemark::getObjId, userUidList));
                remarkMap = remarkList.stream().collect(Collectors.toMap(MeltCloudUserRemark::getObjId, MeltCloudUserRemark::getRemark));
            }
        }
        // 过滤掉用户的敏感信息
        List<User> filterUserList = new ArrayList<>();
        Map<String, String> finalRemarkMap = remarkMap;
        Comment byId = commentService.getById(commentVO.getToUid());
        userList.forEach(item -> {
            User user = new User();
            user.setPic(item.getPic());
            user.setUserId(item.getUserId());
            user.setStatus(item.getStatus());
            String name = item.getNickName();
            if (StringUtils.isNotEmpty(commentVO.getUserUid()) && StringUtils.isNotEmpty(finalRemarkMap.get(item.getUserId()))) {
                name = finalRemarkMap.get(item.getUserId());
            }
            user.setNickName(name);
            user.setIsHasRealName(StrUtil.isNotEmpty(item.getRealName()));
            user.setBlogType(getUserBlogType(byId.getUserUid(),commentVO.getUserUid(),item.getUserId()));
            user.setProvince(IPHelper.getIpProvinceAddr(item.getUserRegip()));
            filterUserList.add(user);
        });
        if(userUidList.contains("admin")){
            User user = new User();
//            user.setPic(item.getPic());
            user.setUserId("admin");
            user.setNickName("平台");
            user.setStatus(1);
            filterUserList.add(user);
        }
        List<User> filterUserListTo = filterUserList.stream().distinct().collect(Collectors.toList());
        Map<String, User> userMap = filterUserListTo.stream().collect(Collectors.toMap(User::getUserId, Function.identity()));


        // 根据一级id，获取点赞数
        List<Comment> allPraiseList = new ArrayList<>();
        if (toCommentUidList.size() > 0) {
            QueryWrapper<Comment> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("blog_uid", commentVO.getBlogUid());
            wrapper1.eq("source", "1");
            wrapper1.in("to_uid",toCommentUidList);
            wrapper1.eq("status", 1);
            wrapper1.eq("type", ECommentType.PRAISE);
            // 查询出该文章下所有的子评论
            allPraiseList = commentService.list(wrapper1);
        }
        //分组 看每个富一代 下回复的数量
        Map<Long, Long> collect1 = allPraiseList.stream().collect(Collectors.groupingBy(t -> t.getToUid(), Collectors.counting()));
        Map<Long, List<Comment>> collect2 = allPraiseList.stream().collect(Collectors.groupingBy(Comment::getToUid));
        // 定义一个评论Map键值对
        resultList.forEach(item -> {
            if(!ObjectUtil.isNull(item.getIp())){
                item.setIp(IPHelper.getIpProvinceAddr(item.getIp()));
            }
            //设置用户信息
            User user = userMap.get(item.getUserUid());
            User toUser = userMap.get(item.getToUserUid());
            if (StringUtils.isNotEmpty(item.getUserUid()) && user!=null) {
                item.setUser(user);
            }
            //如果是三级回复需要回复内容和用户
            if(!item.getToUid().equals(item.getFirstCommentUid()) && toUser!=null){
                Comment comment = commentMap.get(item.getToUid());
                comment.setUserName(toUser.getNickName());
                item.setToComment(comment);
            }
            long l = ObjectUtil.isNull(collect1.get(item.getUid())) ? 0 : collect1.get(item.getUid());
            //点赞数
            item.setPraiseCount(l);
            long l1 = ObjectUtil.isNull(collectReplayCount.get(item.getUid())) ? 0 : collectReplayCount.get(item.getUid());
            //设置回复数
            item.setReplyListCount(l1);
            List<Comment> comments = collect2.get(item.getUid());
            if(StrUtil.isNotEmpty(commentVO.getUserUid()) && !ObjectUtil.isNull(comments)){
                List<Comment> collect3 = comments.stream().filter(s -> s.getUserUid().equals(commentVO.getUserUid())).collect(Collectors.toList());
                item.setPraiseIsMe(collect3.size()>0? true:false);
            }else item.setPraiseIsMe(false);
        });
        pageList.setRecords(resultList);
        return ServerResponseEntity.success(pageList);
    }


    @Operation(summary =  "获取用户的评论列表", description = "获取评论列表")
    @GetMapping("/getListByUser")
    public ServerResponseEntity<Map<String, Object>> getListByUser(PageParam page ,String userId) {
        //分页
        LambdaQueryWrapper<Comment> blogLambdaQueryWrapper = new LambdaQueryWrapper<>();
        blogLambdaQueryWrapper.eq(Comment::getType, ECommentType.COMMENT);
        blogLambdaQueryWrapper.eq(Comment::getStatus,1);
        blogLambdaQueryWrapper.orderByDesc(Comment::getCreateTime);
        // 查找出 我的评论 和 我的回复
        blogLambdaQueryWrapper.and(wrapper -> wrapper.eq(Comment::getUserUid, userId).or().eq(Comment::getToUserUid, userId));
        IPage<Comment> pageList = commentService.page(page, blogLambdaQueryWrapper);
        List<Comment> list = pageList.getRecords();
        List<String> userUidList = new ArrayList<>();
        list.forEach(item -> {
            String userUid = item.getUserUid();
            String toUserUid = item.getToUserUid();
            if (StrUtil.isNotEmpty(userUid)) {
                userUidList.add(item.getUserUid());
            }
            if (StrUtil.isNotEmpty(toUserUid)) {
                userUidList.add(item.getToUserUid());
            }
        });

        // 获取用户列表
        Collection<User> userList = new ArrayList<>();
        if (userUidList.size() > 0) {
            userList = userService.listByIds(userUidList);
        }
        // 过滤掉用户的敏感信息
        List<User> filterUserList = new ArrayList<>();
        userList.forEach(item -> {
            User user = new User();
            user.setPic(item.getPic());
            user.setUserId(item.getUserId());
            user.setNickName(item.getNickName());
            user.setIsHasRealName(StrUtil.isNotEmpty(item.getRealName()));
            filterUserList.add(user);
        });
        List<User> filterUserListTo = filterUserList.stream().distinct().collect(Collectors.toList());
        Map<String, User> userMap = filterUserListTo.stream().collect(Collectors.toMap(User::getUserId, Function.identity()));

        // 将评论列表划分为 我的评论 和 我的回复
        List<Comment> commentList = new ArrayList<>();
        List<Comment> replyList = new ArrayList<>();
        list.forEach(item -> {
            if (StrUtil.isNotEmpty(item.getUserUid())) {
                item.setUser(userMap.get(item.getUserUid()));
            }

            if (StrUtil.isNotEmpty(item.getToUserUid())) {
                item.setToUser(userMap.get(item.getToUserUid()));
            }
            // 设置sourceName
            if (StrUtil.isNotEmpty(item.getSource())) {
                try {
                    item.setSourceName(ECommentSource.valueOf(item.getSource()).getName());
                } catch (Exception e) {
                    log.error("ECommentSource转换异常");
                }
            }
            if (userId.equals(item.getUserUid())) {
                commentList.add(item);
            }
            if (userId.equals(item.getToUserUid())) {
                replyList.add(item);
            }
        });

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("commentList", commentList);
        resultMap.put("replyList", replyList);
        return ServerResponseEntity.success(resultMap);
    }

    /**
     * blogUid 博客id userUid  用户id 内容content 字数限制2048 source固定值 传1    toUid 如果为空代表博客首评 非空 传恢复的评论的id
     * @param commentVO
     * @return
     */
    @Operation(summary =  "增加评论", description = "增加评论")
    @PostMapping("/add")
    public ServerResponseEntity<Comment> add(@RequestBody CommentVO commentVO) {
        if(StrUtil.isEmpty(commentVO.getUserUid())){
            throw new YamiShopBindException("yami.sys.illegalArgument");
        }
        if(StrUtil.isBlank(commentVO.getContent())){
            throw new YamiShopBindException("yami.sys.illegalArgument");
        }
        String userUid = commentVO.getUserUid();
        // 判断该博客是否开启评论功能
        Blog blog = blogService.getById(commentVO.getBlogUid());
        if (!blog.getStatus().equals(1)) {
            throw new YamiShopBindException("yami.dtc.blog.audit.check");
        }
        String blogUserId = blog.getUserUid();
        InteractPowerEnum commentEnum = InteractPowerEnum.instance(blog.getOpenComment());
        switch (commentEnum) {
            case ONESELF:
                if (!userUid.equals(blogUserId)) {
                    throw new YamiShopBindException("yami.dtc.blog.audit.check.manage");
                }
                break;
            case EVERYONE:
                // 所有人可评论
                break;
            case FOLLOW:
                Friend one = friendService.getOne(Wrappers.lambdaQuery(Friend.class).eq(Friend::getUserId, blogUserId).eq(Friend::getFriendId, userUid).eq(Friend::getDelFlag, 0));
                if (!userUid.equals(blogUserId) && Objects.isNull(one)) {
                    throw new YamiShopBindException("yami.dtc.blog.audit.check.people.follow");
                }
                break;
            case FANS:
                Friend one2 = friendService.getOne(Wrappers.lambdaQuery(Friend.class).eq(Friend::getUserId, userUid).eq(Friend::getFriendId, blogUserId).eq(Friend::getDelFlag, 0));
                if (!userUid.equals(blogUserId) && Objects.isNull(one2)) {
                    throw new YamiShopBindException("yami.dtc.blog.audit.check.people.fans");
                }
                break;
            default:
                throw new YamiShopBindException("yami.dtc.blog.audit.check.error");
        }
        User user = userService.getById(userUid);
        this.isPing(userUid, blogUserId);
        // 判断字数是否超过限制
        if (commentVO.getContent().length() > 2048) {
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.dtc.blog.add.check"));
        }
        Comment comment = new Comment();
        comment.setUserUid(userUid);
        comment.setSource(commentVO.getSource());
        comment.setBlogUid(commentVO.getBlogUid());
        comment.setContent(commentVO.getContent());
        comment.setCreateTime(new Date());
        comment.setIp(IPHelper.getIpAddr());
        // 当该评论不是一级评论时，需要设置一级评论UID字段 富二代
        Comment toComment = commentService.getById(commentVO.getToUid());
        if (!ObjectUtil.isNull(commentVO.getToUid())) {
            this.isPing(userUid, toComment.getUserUid());
            // 表示 toComment是非一级评论
            if (!Objects.isNull(toComment.getFirstCommentUid())) {
                comment.setFirstCommentUid(toComment.getFirstCommentUid());
            } else {
                // 表示父评论是一级评论，直接获取UID
                comment.setFirstCommentUid(toComment.getUid());
            }
            commentVO.setToUserUid(toComment.getUserUid());
            // 判断被评论的用户，是否开启了评论提醒
            comment.setToUid(commentVO.getToUid());
            comment.setToUserUid(commentVO.getToUserUid());
            User toUser = userService.getById(commentVO.getToUserUid());
            if (toUser !=null && toComment != null && StringUtils.isNotEmpty(toComment.getContent())) {
                // 发送用户消息
                NotifyTemplateParam shopParam = new NotifyTemplateParam();
                shopParam.setShopId(Constant.PLATFORM_SHOP_ID);
                shopParam.setSendType(SendType.COMMENT_REMINDER.getValue());
                shopParam.setUserId(commentVO.getToUserUid());
                shopParam.setContent(commentVO.getContent());
                shopParam.setFromUserId(userUid);
                shopParam.setBlogId(commentVO.getBlogUid().toString());
                shopParam.setProdId(commentVO.getToUid());
                shopParam.setType(1);
                applicationContext.publishEvent(new SendPersonMessageEvent(shopParam));
            }
            toComment.setUserName(toUser.getNickName());
            if(comment.getFirstCommentUid()==null|| comment.getToUid()==null || !comment.getFirstCommentUid().equals(comment.getToUid())){ //协助前段处理二级评论不返这个参数
                comment.setToComment(toComment);
            }
        } else {
            // 当该评论是一级评论的时候，说明是对 博客详情、留言板、关于我 富一代
            // 判断是否开启通知
            if ( blog.getArticleSource()==1) {
                // 发送用户消息
                NotifyTemplateParam shopParam = new NotifyTemplateParam();
                shopParam.setShopId(Constant.PLATFORM_SHOP_ID);
                shopParam.setSendType(SendType.COMMENT_REMINDER.getValue());
                shopParam.setUserId(blogUserId);
                shopParam.setContent(commentVO.getContent());
                shopParam.setFromUserId(userUid);
                shopParam.setBlogId(commentVO.getBlogUid().toString());
                shopParam.setType(1);
                applicationContext.publishEvent(new SendPersonMessageEvent(shopParam));
            }
            //品类博客 更新博客点赞数量
            blogService.addAndCancelCommentCount(commentVO.getBlogUid() ,true);
        }
        comment.setStatus(1);
        commentService.save(comment);
        comment.setUser(user);
        // 如果是回复某人的评论，那么需要向该用户Redis收件箱中中写入一条记录
        if (StringUtils.isNotEmpty(comment.getToUserUid())) {

        }
        comment.setPraiseIsMe(false);
        comment.setPraiseCount(0l);
        return ServerResponseEntity.success(comment);
    }


    private void isPing(String userId, String toUserId) {
        UserBlock one = userBlockService.getOne(Wrappers.lambdaQuery(UserBlock.class).eq(UserBlock::getUserId, toUserId).eq(UserBlock::getBlockUserId, userId));
        if (Objects.nonNull(one)) {
            throw new YamiShopBindException("yami.dtc.blog.audit.check.prohibit");
        }
        UserBlock one1 = userBlockService.getOne(Wrappers.lambdaQuery(UserBlock.class).eq(UserBlock::getUserId, userId).eq(UserBlock::getBlockUserId, toUserId));
        if (Objects.nonNull(one1)) {
            throw new YamiShopBindException("yami.dtc.blog.audit.check.block");
        }
    }


    /**
     * userUid    status  0 删除1 添加 blogUid 博客id   toUid 非必传 空代表对博客评论进行点赞或者取消点赞    非空代表对子评论进行点赞或者取消点赞
     * @param commentVO
     * @return
     */
    @Operation(summary =  "增加取消点赞（博客或者评论）", description = "增加评论")
    @PostMapping("/addPraise")
    public ServerResponseEntity addPraise(@RequestBody CommentVO commentVO) {
        if(StrUtil.isEmpty(commentVO.getUserUid())){
            throw new YamiShopBindException("yami.sys.illegalArgument");
        }
        if(ObjectUtil.isNull(commentVO.getBlogUid())){
            throw new YamiShopBindException("yami.sys.illegalArgument");
        }
        String userUid = commentVO.getUserUid();
        //查询是否已经有了点赞记录 无聊删除或正常
        LambdaQueryWrapper<Comment> blogLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(!ObjectUtil.isNull(commentVO.getToUid())){
            blogLambdaQueryWrapper.eq(Comment::getToUid, commentVO.getToUid());
        }else{
            blogLambdaQueryWrapper.isNull(Comment::getToUid);
        }
        blogLambdaQueryWrapper.eq(Comment::getBlogUid, commentVO.getBlogUid());
        blogLambdaQueryWrapper.eq(Comment::getUserUid, commentVO.getUserUid());
        blogLambdaQueryWrapper.eq(Comment::getType, 1);//圈子
        Comment res = commentService.getOne(blogLambdaQueryWrapper);
        //点赞
        if(ObjectUtil.isNull(res)&&commentVO.getStatus()==1){
            Comment comment = new Comment();
            if (!ObjectUtil.isNull(commentVO.getToUid())) {
                //用户发消息 点赞
                Comment toComment = commentService.getById(commentVO.getToUid());
                User toUser = userService.getById(toComment.getUserUid());
                comment.setToUid(commentVO.getToUid());
                comment.setToUserUid(toUser.getUserId());
                if (toUser !=null&& toComment != null && StringUtils.isNotEmpty(toComment.getContent())) {
                    // 发送用户消息
                    NotifyTemplateParam shopParam = new NotifyTemplateParam();
                    shopParam.setShopId(Constant.PLATFORM_SHOP_ID);
                    shopParam.setSendType(SendType.LIKES_REMINDER.getValue());
                    shopParam.setUserId(toComment.getUserUid());
                    shopParam.setToTypeName("评论");
                    shopParam.setProdId(commentVO.getToUid());
                    shopParam.setFromUserId(userUid);
                    shopParam.setBlogId(commentVO.getBlogUid().toString());
                    shopParam.setType(2);
                    applicationContext.publishEvent(new SendPersonMessageEvent(shopParam));
                }
            }else{
                //点赞博客 更新博客点赞数量
                blogService.addAndCancelPraiseCount(commentVO.getBlogUid() ,true);
                Blog blog = blogService.getById(commentVO.getBlogUid());
                if(blog.getArticleSource()==1){
                    // 发送用户消息
                    NotifyTemplateParam shopParam = new NotifyTemplateParam();
                    shopParam.setShopId(Constant.PLATFORM_SHOP_ID);
                    shopParam.setSendType(SendType.LIKES_REMINDER.getValue());
                    shopParam.setUserId(blog.getUserUid());
                    shopParam.setToTypeName("动态");
                    shopParam.setFromUserId(userUid);
                    shopParam.setBlogId(commentVO.getBlogUid().toString());
                    shopParam.setType(2);
                    applicationContext.publishEvent(new SendPersonMessageEvent(shopParam));
                }
            }
            comment.setType(ECommentType.PRAISE);
            comment.setBlogUid(commentVO.getBlogUid());
            comment.setSource("1");
            comment.setUserUid(userUid);
            comment.setStatus(1);
            comment.setCreateTime(new Date());
            comment.setIp(IPHelper.getIpAddr());
            commentService.save(comment);

        }else if(!ObjectUtil.isNull(res)&&commentVO.getStatus()==1){
            //点赞
            res.setStatus(1);
            res.setUpdateTime(new Date());
            commentService.updateById(res);
            if (ObjectUtil.isNull(commentVO.getToUid())) {
                //点赞博客 更新博客点赞数量
                blogService.addAndCancelPraiseCount(commentVO.getBlogUid() ,true);
            }
        }else if(!ObjectUtil.isNull(res)&&commentVO.getStatus()==0){
            //取消点赞
            res.setStatus(0);
            res.setUpdateTime(new Date());
            commentService.updateById(res);
            if (ObjectUtil.isNull(commentVO.getToUid())) {
                //点赞博客 更新博客点赞数量
                blogService.addAndCancelPraiseCount(commentVO.getBlogUid() ,false);
                LambdaQueryWrapper<NotifyLog> wrapper1 = new LambdaQueryWrapper<>();
                wrapper1.in(NotifyLog::getBlogId, res.getBlogUid());
                wrapper1.eq(NotifyLog::getUserId,userUid);
                wrapper1.eq(NotifyLog::getType,2);
                List<NotifyLog> list1 = notifyLogService.list(wrapper1);
                //评论和点赞集合合并
                list1.forEach(item -> {
                    item.setStatus(-1);
                });
                notifyLogService.updateBatchById(list1);
            }else{
                //删除点赞消息
                LambdaQueryWrapper<NotifyLog> wrapper1 = new LambdaQueryWrapper<>();
                wrapper1.in(NotifyLog::getProdId, res.getUid());
                wrapper1.eq(NotifyLog::getUserId,userUid);
                wrapper1.eq(NotifyLog::getType,2);
                List<NotifyLog> list1 = notifyLogService.list(wrapper1);
                //评论和点赞集合合并
                list1.forEach(item -> {
                    item.setStatus(-1);
                });
                notifyLogService.updateBatchById(list1);
            }
        }
        return ServerResponseEntity.success();
    }
    /**
     * 通过UID删除评论
     *
     * @param commentVO
     * @return
     */
    @Operation(summary =  "删除评论", description = "删除评论")
    @PostMapping("/delete")
    public ServerResponseEntity deleteBatch(@RequestBody CommentVO commentVO) {


        Comment comment = commentService.getById(commentVO.getUid());
        // 判断该评论是否能够删除
        if (!comment.getUserUid().equals(commentVO.getUserUid())) {
            return ServerResponseEntity.showFailMsg("该数据无权限访问！");
        }
        // 获取该评论下的子评论进行删除
        // 传入需要被删除的评论 【因为这里是一条，我们需要用List包装一下，以后可以用于多评论的子评论删除】
        List<Comment> commentList = new ArrayList<>(1);
        commentList.add(comment);

        // 判断删除的是一级评论还是子评论
        Long firstCommentUid ;
        if (!ObjectUtil.isNull(comment.getFirstCommentUid())) {
            // 删除的是子评论
            firstCommentUid = comment.getFirstCommentUid();
        } else {
            // 删除的是一级评论
            firstCommentUid = comment.getUid();
        }

        // 获取该评论一级评论下所有的子评论
        LambdaQueryWrapper<Comment> blogLambdaQueryWrapper = new LambdaQueryWrapper<>();
        blogLambdaQueryWrapper.eq(Comment::getFirstCommentUid, firstCommentUid);
        blogLambdaQueryWrapper.eq(Comment::getStatus, 1);
        List<Comment> toCommentList = commentService.list(blogLambdaQueryWrapper);
        List<Comment> resultList = new ArrayList<>();
        commentService.getToCommentList(comment, toCommentList, resultList);
        // 将所有的子评论也删除
        resultList.add(comment);//添加本身
        if (resultList.size() > 0) {
            //删除子级点赞评论
            List<Long> collect = resultList.stream().map(s -> s.getUid()).collect(Collectors.toList());
            LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(Comment::getToUid, collect);
            wrapper.eq(Comment::getStatus,1);//正常
            List<Comment> list = commentService.list(wrapper);
            //评论和点赞集合合并
            resultList.addAll(list);
            resultList.forEach(item -> {
                item.setStatus(0);
                item.setUpdateTime(new Date());
            });
            commentService.updateBatchById(resultList);

            //删除评论消息
            LambdaQueryWrapper<NotifyLog> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.in(NotifyLog::getProdId, collect);
            List<NotifyLog> list1 = notifyLogService.list(wrapper1);
            //评论和点赞集合合并
            list1.forEach(item -> {
                item.setStatus(-1);
            });
            notifyLogService.updateBatchById(list1);
        }
        //删除博客品论 更新博客点赞数量
        if(ObjectUtil.isNull(comment.getFirstCommentUid())){
            blogService.addAndCancelCommentCount(comment.getBlogUid() ,false);
        }
        return ServerResponseEntity.success();
    }



    /**
     * 获取用户点赞信息
     *
     * @return
     */
    @Operation(summary =  "获取用户点赞信息", description = "增加评论")
    @GetMapping("/getPraiseListByUser")
    public ServerResponseEntity getPraiseListByUser(PageParam page ,String userUid,String type) {
        //获取我发的博客
        LambdaQueryWrapper<Blog> blogLambdaQueryWrapper = new LambdaQueryWrapper<>();
        blogLambdaQueryWrapper.eq(Blog::getUserUid, userUid);
        blogLambdaQueryWrapper.eq(Blog::getArticleSource, 1);
        blogLambdaQueryWrapper.eq(Blog::getStatus,1);//审核通过
        List<Blog> list = blogService.list(blogLambdaQueryWrapper);
        //分类整理
        List<Long> collect = list.stream().map(s -> s.getUid()).collect(Collectors.toList());
        Map<Long, Blog> blogMap = list.stream().collect(Collectors.toMap(Blog::getUid, Function.identity()));
        //获取点赞我的博客或者点赞我的评论 点赞数据集合
        QueryWrapper<Comment> queryWrappe = new QueryWrapper<>();
        queryWrappe.eq("to_user_uid", userUid);
        queryWrappe.and(wrappe->wrappe.in("blog_uid", collect).isNull("to_user_uid").or().eq("to_user_uid", userUid));
        queryWrappe.eq("type", type);
        queryWrappe.eq("status", "1");
        queryWrappe.orderByDesc("create_time");
        IPage<Comment> pageList = commentService.page(page, queryWrappe);
        List<Comment> praiseList = pageList.getRecords();
        //获取点赞我的品论的ids
        List<Long> uids = new ArrayList<>();
        List<String> userUidList = new ArrayList<>();
        praiseList.forEach(item -> {
            if(!ObjectUtil.isNull(item.getToUid())){
                uids.add(item.getToUid());
            }
            userUidList.add(item.getUserUid());
        });
        //获取点赞的评论对象集合
        LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Comment::getUid, uids);
        wrapper.eq(Comment::getStatus,1);//正常
        List<Comment> listComment = commentService.list(wrapper);
        Map<Long, Comment> commentMap = listComment.stream().collect(Collectors.toMap(Comment::getUid, Function.identity()));

        Collection<User> userList = new ArrayList<>();
        if (userUidList.size() > 0) {
            userList = userService.listByIds(userUidList);
        }
        // 过滤掉用户的敏感信息
        List<User> filterUserList = new ArrayList<>();
        userList.forEach(item -> {
            User user = new User();
            user.setPic(item.getPic());
            user.setUserId(item.getUserId());
            user.setNickName(item.getNickName());
            user.setIsHasRealName(StrUtil.isNotEmpty(item.getRealName()));
            filterUserList.add(user);
        });
        if(userUidList.contains("admin")){
            User user = new User();
//            user.setPic(item.getPic());
            user.setUserId("admin");
            user.setNickName("平台");
            filterUserList.add(user);
        }
        List<User> filterUserListTo = filterUserList.stream().distinct().collect(Collectors.toList());
        Map<String, User> userMap = filterUserListTo.stream().collect(Collectors.toMap(User::getUserId, Function.identity()));


        praiseList.forEach(item -> {
            if (StrUtil.isNotEmpty(item.getUserUid())) {
                item.setUser(userMap.get(item.getUserUid()));
            }
            //添加品论对象
            if(!ObjectUtil.isNull(item.getToUid())){
                Comment comment = commentMap.get(item.getToUid());
                item.setToComment(comment);
            }
            //如果品论的是博客
            if(ObjectUtil.isNull(item.getToUid())){
                Blog blog = blogMap.get(item.getBlog());
                item.setBlog(blog);
            }
        });
        pageList.setRecords(praiseList);
        return ServerResponseEntity.success(pageList);
    }
}
